#include "../../include/online/Configuration.hpp"
#include "../../include/online/CacheManager.hpp"
#include "../../include/server/Logger.hpp"
#include <iostream>

using std::cout;
using std::endl;

CacheManager *CacheManager::_pInstance = getInstance();

CacheManager::CacheManager() 
    //_cacheNum取工作线程数，要求cacheNum和工作线程数一致
    : _cacheNum(stoul(Configuration::getInstance()->getConfigMap()["workernum"])),
    _maxRecordNum(stoul(Configuration::getInstance()->getConfigMap()["recordnum"])),
    _caches(_cacheNum, _maxRecordNum) {

    }

CacheManager *CacheManager::getInstance() {
    if(!_pInstance) {
        _pInstance = new CacheManager();
        atexit(destroy);
    }
    return _pInstance;
}

CacheGroup &CacheManager::getCacheGroup(size_t idx) {
    return _caches[idx];
}

void CacheManager::destroy() {
    cout << "CacheManager:destroy()" << endl;
    if(_pInstance) {
        delete _pInstance;
        _pInstance = nullptr;
    }
}

void CacheManager::sync() {
    //选中主cache，并将其只读位设置为true
    cout << "synchronize mainCache and followedCache" << endl;
    auto &first_group = _caches[0];
    first_group._readOnly = true;
    
    //将所有从cache的待更新记录_pendingUpdateRecord
    //更新到主Cache
    for(auto &group : _caches) {
        //先选中待更新的从cache的更新集合
        auto &pendingCache = group._pendingUpdateCache;
        for (auto &record : pendingCache._resultList) {
            //待更新记录的内容逐条记录插入到主cache中
            first_group.insertRecord(record.first, record.second);
        }
        //更新完毕以后当前Cache的待更新集合设为空
        pendingCache.clear();
    }
    
    //将主Cache的内容同步到所有从Cache中
    for(auto &group : _caches) {
        group._readOnly = true;
        group.update(first_group);
        group._readOnly = false;
    }
    //mainCache恢复为可写状态
    first_group._readOnly = false;
}

